interface RetryConfig {
  maxRetries: number
  baseDelay: number
  maxDelay: number
}

export class ApiClient {
  private defaultRetryConfig: RetryConfig = {
    maxRetries: 3,
    baseDelay: 1000,
    maxDelay: 10000
  }

  async request<T>(
    url: string, 
    options: RequestInit = {},
    retryConfig: Partial<RetryConfig> = {}
  ): Promise<T> {
    const config = { ...this.defaultRetryConfig, ...retryConfig }
    
    for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
      try {
        const response = await fetch(url, options)
        
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`)
        }
        
        return await response.json()
      } catch (error) {
        if (attempt === config.maxRetries) {
          throw error
        }
        
        // 计算延迟时间（指数退避）
        const delay = Math.min(
          config.baseDelay * Math.pow(2, attempt),
          config.maxDelay
        )
        
        await new Promise(resolve => setTimeout(resolve, delay))
      }
    }
    
    throw new Error('Max retries exceeded')
  }

  // 便捷方法
  async get<T>(url: string, retryConfig?: Partial<RetryConfig>): Promise<T> {
    return this.request<T>(url, { method: 'GET' }, retryConfig)
  }

  async post<T>(
    url: string, 
    data?: any, 
    retryConfig?: Partial<RetryConfig>
  ): Promise<T> {
    return this.request<T>(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: data ? JSON.stringify(data) : undefined
    }, retryConfig)
  }

  async put<T>(
    url: string, 
    data?: any, 
    retryConfig?: Partial<RetryConfig>
  ): Promise<T> {
    return this.request<T>(url, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
      },
      body: data ? JSON.stringify(data) : undefined
    }, retryConfig)
  }

  async delete<T>(url: string, retryConfig?: Partial<RetryConfig>): Promise<T> {
    return this.request<T>(url, { method: 'DELETE' }, retryConfig)
  }
}

export const apiClient = new ApiClient()
